package cn.niu.ts;

import ch.qos.logback.core.encoder.ByteArrayUtil;
import org.apache.log4j.Logger;

import java.io.ByteArrayOutputStream;
import java.io.IOException;


public class PesPackage {

    /**
     * 获取音频的pes
     *
     * @param buf
     * @param pts
     * @return
     * @throws IOException
     */
    public static byte[] getPes(byte[] buf, long pts) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        //写入 Packet start code prefix 0x000001  3bytes
        byteArrayOutputStream.write(ByteUtil.hexStringToByteArray("000001"));
        //写入 Stream id Audio streams (0xC0-0xDF) 1bytes
        byteArrayOutputStream.write(0xC0);
        //写入此后的长度 2bytes  3bytes信息 + 5bytes长度
        int length = 8 + buf.length;

        byteArrayOutputStream.write(length >> 8 & 0xff);
        byteArrayOutputStream.write(length & 0xff);

        // Marker bits 占2bit 固定为 10
        // PES scrambling control：加密模式，占2bit；00未加密，01或10或11由用户定义；
        // PES priority：有效负载的优先级，占位1bit；值为1比值为0的负载优先级高；
        // Data alignment indicator：数据定位指示器，占位1bit；
        // Copyright：版权信息，1为有版权，0无版权，占位1bit；
        // Original or copy：原始或备份，1为原始，0为备份，占位1bit；
        // 写入 10000000
        byteArrayOutputStream.write(0x80);

        // PTS_DTS_flags：PTS和DTS标志位，占位2bit；10表示首部有PTS字段，11表示有PTS和DTS字段，00表示都没有，01被禁止，不会出现此种情况；
        // ESCR_flag：ESCR标志，占位1bit；1表示首部有ESCR字段，0则无此字段
        // ES_rate_flag：ES_rate字段，占位1bit；1表示首部有此字段，0无此字段；
        // DSM_trick_mode_flag：占位1bit；1表示有8位的DSM_trick_mode_flag字段，0无此字段；
        // Additional_copy_info_flag：占位1bit；1表示首部有此字段，0表示无此字段；
        // PES_CRC_flag：占位1bit；置1表示PES分组有CRC字段，0无此字段；
        // PES_extension_flag：占位1bit；扩展标志位，置1表示有扩展字段，0无此字段；
        // 写入 10000000
        byteArrayOutputStream.write(0x80);

        //PES header data length：(UI)PES首部中可选字段和填充字段的长度；占位8bit(1bytes)；
        //可选字段的内容由上面7个flags来进行控制(这里只有pts可选字段，占5bytes,其余为空)；
        // 写入 0x05
        byteArrayOutputStream.write(0x05);

        //写入pts 5个字节
        // 4bit start_code 同PTS_DTS_flags 0010;
        // 3bit 数据 1bit 固定为1
        // 15bit数据 1bit 固定为1
        // 15bit数据 1bit 固定为1~
        // 共5字节
        // 获取pts方法：PTS1 第1个字节 PTS2 2,3字节 PTS3 4,5字节
        // PTS =（PTS1 & 0x0e) << 29 + (PTS2 & 0xfffe) << 14 + (PTS3 & 0xfffe ) >> 1;
        byteArrayOutputStream.write((int) (0b00100000 | ((pts >> 29) | 0b1)));
        byteArrayOutputStream.write((int) ((pts >> 21) & 0xff));
        byteArrayOutputStream.write((int) (((pts >> 14) & 0xff) | 0b1));
        byteArrayOutputStream.write((int) ((pts >> 7) & 0xff));
        byteArrayOutputStream.write((int) (((pts << 1) & 0xff) | 0b1));

        //写入数据
        byteArrayOutputStream.write(buf);

        return byteArrayOutputStream.toByteArray();
    }


}
